查看原文
其他

更精准更简洁: Flutter 改进错误信息提示

Flutter 谷歌开发者 2021-08-05


作者 / 董韬, UX Researcher, Google


在编写计算机程序时,即使经验最丰富的开发者也不可避免地会出现失误。想要解决问题,第一步通常是读取控制台中显示的报错信息。但是研究表明,程序员,尤其是新手,很难理解报错信息,更不用说采取针对性的行动了。


  • On Compiler Error Messages: What They Say and What They Mean

    https://www.hindawi.com/journals/ahci/2010/602570/abs/


不可否认,Flutter 在帮助开发者从报错中找到 bug 症结的这个事情上并没有做得很好。来自控制台中的报错输出经常十分冗长,并且通常不会清楚地说明如何将报错追溯到代码中的特定位置。最近,我们一直致力于解决这两个问题。在这篇文章中,我将介绍我们对提高 Flutter 报错信息 “信噪比” 方面的初步尝试,以及我们为此所做的相关研究。



引入结构化报错信息


在最新版 IntelliJ / Android Studio 的 Flutter 插件和 VS Code 的 Flutter 扩展中,我们发布了一个新功能。这项功能能够以丰富而简洁的格式显示报错信息。日志记录控制台现在可以显示具备以下几项改进的报错信息:

  1. 用红色突出显示报错信息摘要

  2. 在节段之间添加空白,让信息更易于浏览

  3. 如果报错信息包含解决错误的提示,用高亮文字来让它们更突出

  4. 折叠信息中的长列表和树状图


以下截图展示了由布局溢出 (overflow) 引发的报错,并使用蓝色圆圈标出了上述四方面的改进:

△ 改进过的报错信息截图
值得指出的是,以上所有内容都可以放置在同一个屏幕中,因此您可以一目了然地了解问题。我们在减少信息中 “噪音” 的过程中不会删除任何有用的细节信息,以满足开发者在特定修复场景下的需要。

相比之下,原始的报错信息显示方式更加密集且缺乏结构,因此很难从中发现有用的信息来修复错误:

△ 同一个 RenderFlex Overflow 错误在以前会如上显示
目前,我们在 Flutter 框架中重构了大约 85% 的报错信息,以便利用这个新的展示方式。其余有关报错信息的改进也将逐渐实现。我们还打算根据用户反馈信息,优化报错信息的整体呈现方式。


我们如何做到这些改进


报错信息的可用性是一个多方面的问题。报错信息的内容、结构和呈现都有助于您理解报错并修复问题。我们知道 Flutter 中的报错信息通常会提供有用的内容,但是需要筛选的信息数量太大,从而容易错过有用的信息。 

作为示例,我们来看看 “Missing Material widget” 这条报错信息。当 widget 在其祖先树中检索 Material widget 但未找到时,系统就会显示这条报错信息。这个报错的信息很难弄清楚,甚至有用户专门去 StackOverflow 寻求帮助。高票答案指出的关键信息其实已经包含在了报错信息中,只不过用户要么找不到所需的信息,要么无法理解。解决这个问题并不需要给出额外的信息。

△ StackOverflow 上关于 “找不到 Material widget” 的问题
  • 上文中提到的 StackOverflow 问题
    https://stackoverflow.com/questions/43947552/using-textfield-throws-no-material-widget-found-error


呈现报错信息的新方法


StackOverflow 上的这个问题很有启发性。它表明,报错信息中的各种信息所占的权重是不同的。这个问题也激发了我们的思考,如何才能使有用的信息更加显眼,这意味着我们需要减少视觉中的干扰。通过应用相关的视觉感知理论和 UX设计技巧,我们为该报错信息提出了三种改进的设计方案: 颜色、分段和省略。


  • 视觉感知理论

    https://www.interaction-design.org/literature/article/laws-of-proximity-uniform-connectedness-and-continuation-gestalt-principles-2 

  • UX 设计技巧

    https://www.nngroup.com/articles/progressive-disclosure


为了创建 “颜色” 这个方案,我们分析了报错信息中不同种类信息的相对重要性,并提出了一种简单的配色方案:

  • 以红色显示报错的单行摘要

  • 以蓝色显示与报错关联的对象

  • 以灰色显示通常无需了解的细节

△ 改进方案 - 颜色

下一个方案是 “分段”。我们在报错信息中添加了空行,将其分成段落。我们还添加了诸如 “说明 (Explanation)” 和 “潜在修复方法 (Potential Fix)” 之类的段落标题,以使信息更易于浏览。

△ 改进方案 – 分段

最后,“省略” 这个方案在呈现报错信息时采用渐进式披露这个设计技巧,并活用了现代 IDE 的功能。例如,我们在显示 TextField widget 的参数列表和 widget 的祖先列表时,只显示前三个,然后就使用省略号 (…) 进行折叠。要查看列表的完整内容,只需单击省略号即可。这样生成的报错信息比原始信息短得多,让开发者可以更容易地关注信息中的更高级别元素。

△ 改进方案 – 省略
  • 渐进式披露
    https://www.nngroup.com/articles/progressive-disclosure/


我们有充分的理由相信这些方案可以帮助开发者,但我们不确定能否证明为实现它们而付出的成本是否合理。为了实现上述这些设计方案,我们需要让 Flutter 框架将结构化的报错数据发送到 IDE,这样 IDE 才能针对不同部分进行布局 (例如摘要、细节和提示),并折叠不太重要的信息。我们需要回答这样一个问题: 对于开发者体验的潜在改进是否足以让我们重构 Flutter 的报错 API,以及用这个新的 API 重构现有的数百条报错信息。因此,我们决定进行一项实验,以了解实现结构化报错信息的 “性价比”。



实验


为了比较三种方案与原始报错信息的可用性差别,我们使用基于情景的问卷进行了在线实验。我们招募了 52 名 Flutter 开发者,他们被随机分配到四个实验组中的一个。我们把原始报错信息显示给对照组,把变体分别显示给三个试验组。在非常有限的时间内,我们要求被试描述报错信息的大意,以及如何修复这个错误。您可以在今年早些时候我们发表在 CHI 2019 的同行评审论文中找到详细的研究设计。


  • CHI 2019 研究论文

    https://w.url.cn/s/AbfbDSg


这次实验的结果让我们惊喜。三个实验组的被试对报错信息的理解准确度都明显强过对照组。换句话说,无论使用哪种方案,在有限时间内正确理解报错信息的参与者的比例都要大大高于原始对照组。下图显示,当参与者需要在 45 秒内读取报错信息时,分段变体的性能优于原始格式约 38 个百分点。

△ 三种方案的 45 秒报错信息解读准确度
都明显高于原始格式

同样,在确定解决方案时,报错信息的所有实验方案都优于原始格式。

△ 三种方案的报错信息解决准确度都明显高于原始格式

当我们要求参与者比较原始报错信息和他们在实验中使用的方案时,他们解释了为什么他们更喜欢这些新的报错呈现方案。以下是一些例子 (括号内的注释是笔者添加的)。
“右边的报错消息 (指 ‘颜色’ 方案) 改进很明显,关键的短信息以红色显示,受影响的 widget 则以蓝色显示。” 


“隐藏整个 widget 对象 (指 ‘省略’ 方案) 可以减少干扰,我因此可以轻松找到报错发生的原因。” 


“B 方案 (指 ‘分段’ 方案) 更容易理解。这些分段非常明晰,我在快速浏览时很容易知道下一步要跳到哪里。”
有了实验得出的有力证据,我们决定针对结构化报错信息进行资源投入。这是一段漫长的旅程,但我们很高兴地看到,重构的报错 API 为未来的创新提供了坚实的基础,帮助开发者更快地修复 Flutter 项目中的错误。


  • 重构报错 API
    https://master-api.flutter.dev/flutter/foundation/ErrorSummary-class.html



报错信息下一步怎么做


对于 UI 代码抛出的报错信息,我们可以在信息中嵌入图像、动画甚至交互式的 widget 树,以最大化它的信息价值。我们计划在 Dart DevTools 的控制台上开展一些更宏大的试验,因为在那里我们不受 IntelliJ 和 VS Code 的可扩展性限制。


  • 了解 Dart DevTools
    https://flutter.dev/docs/development/tools/devtools/overview



欢迎您来帮助我们


部分 Flutter 报错信息还没有用新的 API 进行重构,因此它们暂时无法充分利用这种新的结构化呈现方式。我们正在优先处理覆盖面最广的 Flutter 报错信息。您可以通过我们的 GitHub 问题跟踪专页让我们知道哪些报错信息更有用,或是在我们的 IntelliJ 和 VS Code 插件的代码库中提出改进报错信息呈现方式的建议。 


  • GitHub 问题跟踪专页
    https://github.com/flutter/flutter/issues/new?labels=a:%20error%20message



鸣谢


Flutter 团队的前 UX 研究实习生 Kandarp Khandwala 为本文所述的研究做出了积极贡献。我们还要感谢所有参与实验的 Flutter 开发者。


  • 扩展阅读 Dart Code
    https://dartcode.org/releases/v3-4/#improved-flutter-errors
  • Flutter 社区中文资源
    https://flutter-io.cn/


 点击屏末 | 阅读原文 | 即刻开启 Flutter 开发之旅


  想了解更多 Flutter 内容?


  • 在公众号首页发送关键词 “Flutter”,获取相关历史技术文章;

  • 还有更多疑惑?欢迎点击菜单 “联系我们” 反馈您在开发过程中遇到的问题。

推荐阅读




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存